package tcp.command;

import handlers.ClientStatusHandler;
import handlers.FileDeletionHandler;
import handlers.FileHandler;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;

import constants.NetworkConstants;

public class CommandHandler implements Runnable{
	
	private CommandManager manager;
	private Socket commandSocket;
	
	public CommandHandler(Socket socket, CommandManager manager) {
		this.commandSocket = socket;
		this.manager = manager;
	}
	public void run() {
		System.out.println(this.getClass().getSimpleName()+" : Command calling");
		BufferedReader in = null;
		PrintWriter out = null;
		try {

			out = new PrintWriter(this.commandSocket.getOutputStream(),true);
			in = new BufferedReader(new InputStreamReader(this.commandSocket.getInputStream()));
			
			String action = in.readLine() ;
			System.out.println(this.getClass().getName()+": Action "+action);
			if(action.equalsIgnoreCase(NetworkConstants.COMMAND_ACTON_STATUS)){
				this.processStatusRequest(out, in);
			}
			if(action.equalsIgnoreCase(NetworkConstants.COMMAND_ACTION_REPLICATE)){
				this.processFileReplication(out, in);
			}
			if(action.equalsIgnoreCase(NetworkConstants.COMMAND_ACTION_FILE_MOVE)){
				this.processFileMove(out, in);
			}
			if(action.equalsIgnoreCase(NetworkConstants.COMMAND_ACTION_CLIENT_UPDATE)){
				this.processClientUpdate(out, in);
			}
			if(action.equalsIgnoreCase(NetworkConstants.COMMAND_ACTION_FILE_DELETE)){
				this.processFileDeletion(out, in);
			}
			if(action.equalsIgnoreCase(NetworkConstants.COMMAND_ACTION_UPLOAD_FILE)){
				this.processUploadFileRequest(out,in);
			}
			
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
				in.close();
				this.commandSocket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			out.close();
		}
	}
	private void processStatusRequest(PrintWriter out, BufferedReader in){
		//Return a String with the RDF for the File Store Node
		String status = this.manager.getStatusHandler().getStatus();
		out.println("STATUS OK");
		out.flush();
		out.println(status);
		out.flush();
		out.println("EOF");
	}
	private void processFileReplication(PrintWriter out, BufferedReader in){
		try {
			
			String param = null;
			ArrayList<String> listOfParams = new ArrayList<String>();
			while((param = in.readLine()) != null && !param.equalsIgnoreCase("EOF")){
				if(!param.equalsIgnoreCase("EOF")){
					listOfParams.add(param);
				}
			}
			if(listOfParams.size() == 3){
				this.manager.getReplicationHandler().handleReplicationRequest(listOfParams.get(0), listOfParams.get(1), Integer.parseInt(listOfParams.get(2)));
			}	
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	private void processFileMove(PrintWriter out, BufferedReader in){
		
	}
	private synchronized void processClientUpdate(PrintWriter out, BufferedReader in){
		String model = null;
		StringBuffer sb = new StringBuffer();
		try {
			while((model = in.readLine())!= null && !model.equalsIgnoreCase("EOF")){
				if(!model.equalsIgnoreCase("EOF")){
					sb.append(model);
				}
			}
			if(sb.length() > 0){
				ClientStatusHandler handler = this.manager.getClientStatusHandler();
				if(handler != null){
					handler.handleGovenorStatus(sb.toString());
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	private void processFileDeletion(PrintWriter out, BufferedReader in){
		
		String fileToDelete = null;
		StringBuffer sb = new StringBuffer();
		try{
			while((fileToDelete = in.readLine())!= null && !fileToDelete.equalsIgnoreCase("EOF")){
				if(!fileToDelete.equalsIgnoreCase("EOF")){
					sb.append(fileToDelete);
				}
			}
			if(sb.length() > 0){
				FileDeletionHandler handler = this.manager.getDeleteFileHandler();
				if(handler != null){
					handler.deleteFile(sb.toString());
				}
			}
		}catch(IOException e){
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	private void processUploadFileRequest(PrintWriter out, BufferedReader in){
		ArrayList<String> listOfParams = new ArrayList<String>();
		String param = null;
		try{
			while((param = in.readLine())!= null && !param.equalsIgnoreCase("EOF")){
				if(!param.equalsIgnoreCase("EOF")){
					listOfParams.add(param);
				}
			}
			this.manager.getUploadRequestHandler().handleUploadResponse(listOfParams.get(0),listOfParams.get(1), Integer.parseInt(listOfParams.get(2)));
		}catch(IOException e){
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
